home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #46 (Jul 89) / Terminal / term.asm < prev    next >
Assembly Source File  |  1989-04-17  |  20KB  |  814 lines

  1. ; File: Term.asm
  2. ;----------------------------------------------------------------------
  3. ; Term.asm is a simple terminal program, that shows how to use low
  4. ; level serial I/O routines.
  5. ; written by Frank Henriquez
  6. ;
  7. ; The code that handles the transfers between the clipboard and Text Edit
  8. ; is based on the code in chapter 3 of Dan Weston's
  9. ; "The Complete Book of Macintosh Assembly Language Programming Volume II"
  10.  
  11. ; Some coding ideas were borrowed from the program "Rose.Asm"
  12. ; by Victor Barger, that appeared in the January 1987 issue of MacTutor.
  13. ;
  14. ;  7/15/87    Initial Turbo Pascal version, using Quickdraw for text.
  15. ;   9/1/87    assembly language translation.
  16. ; 10/10/87    modified to use TextEdit.
  17. ; 10/18/87    fully functional version.
  18. ; 10/20/87    text handling improved, Baud rates added.
  19. ;  1/14/88    modified to use external serial I/O routines.
  20. ;----------------------------------------------------------------------
  21. ; Register usage:
  22. ; d0: general purpose, also holds the menu#.
  23. ; d1: general purpose, also menu item# and the Modify value.
  24. ; d2: general purpose.
  25. ; d3, d4, d5, d6, d7 : not used.
  26.  
  27. ; a0: general purpose, used for buffers and parameter blocks.
  28. ; a1: general purpose.
  29. ; a2: holds TextEdit handle.
  30. ; a3: general purpose.
  31. ; a4, a6 : not used.
  32. ; a5, a7 : system use.
  33. ;----------------------------------------------------------------------
  34. ; pre-compiled routines from Serial I/O.asm
  35.  
  36.     XDEF    OpenSerial
  37.     XDEF    Config
  38.     XDEF    GetSerial
  39.     XDEF    PutSerial
  40.     XDEF    SetBuf
  41.  
  42. ; Standard include files
  43.  
  44. Include     Traps.D
  45. Include     Toolequ.D
  46. Include        Sysequ.D
  47. Include     Quickequ.D
  48.  
  49.  
  50. ;----------- Program constants -------------
  51.  
  52. AppleMenu    equ    1        ; Apple
  53. AboutItem    equ    1        ; First item in Apple menu
  54.  
  55. FileMenu    equ    2        ; File
  56. QuitItem     equ    1        ; First item in File menu
  57.  
  58. EditMenu    equ    3        ; Edit
  59. UndoItem    equ    1        ; Items in Edit menu
  60. CutItem        equ    3
  61. CopyItem    equ    4
  62. PasteItem    equ    5
  63. ClearItem    equ    6
  64.  
  65. CmdMenu        equ    4        ; Command menu
  66. EraseItem    equ    1        ; Erase screen
  67.  
  68. B300        equ    3        ;  300 baud
  69. B1200        equ    4        ; 1200 baud
  70. B2400        equ    5        ; 2400 baud
  71. B9600        equ    6
  72.  
  73. AboutDialog    equ    1        ; About dialog
  74. ButtonItem    equ    1        ; First item in DITL
  75.  
  76. WindID        equ    1
  77.  
  78. PortA        equ    -6
  79. PortB        equ    -8
  80.  
  81. baud300        equ    380
  82. baud1200    equ    94
  83. baud2400    equ    46
  84. baud9600    equ    10
  85. stop10        equ    16384
  86. noParity    equ    8192
  87. data8        equ    3072
  88.  
  89. Config300    equ    baud300  + data8 + stop10 + noParity
  90. Config1200    equ    baud1200 + data8 + stop10 + noParity
  91. Config2400    equ    baud2400 + data8 + stop10 + noParity
  92. Config9600    equ    baud9600 + data8 + stop10 + noParity
  93.  
  94.  
  95.  
  96. ;---------- Program starts here ------------
  97.  
  98. Start
  99.     bsr.s    InitSerial
  100.     bsr    InitManagers
  101.     bsr    SetupMenu
  102.     bsr    SetupWindow
  103.     bsr    SetupTextEdit
  104.     bsr    CliptoTE
  105.  
  106. EventLoop
  107.     _SystemTask            ; check for DA calls
  108.     move.l    a2,-(sp)        ; get handle to text record
  109.     _TEIdle                ; blink cursor etc.
  110.     bsr    GetSerCh        ; get a character from the modem port
  111.     bsr    PutScreen        ; and put it on the screen
  112.     clr.w    -(sp)
  113.     move.w    #$0fff,-(sp)        ; look for all events
  114.     pea    EventRecord(a5)
  115.     _GetNextEvent            ; get the next event
  116.     move.w    (sp)+,d0
  117.     beq.s    EventLoop        ; loop until an event
  118.     bsr    HandleEvent        ; take care of the event
  119.     beq.s    EventLoop        ; time to quit if not zero
  120.     move.l    a2,-(sp)
  121.     _TEDispose
  122.     clr.w    -(sp)
  123.     move.w    #PortA,-(sp)        ; modem port
  124.     clr.l    -(sp)            ; reset default serial buffer
  125.     jsr    SetBuf
  126.     addq.l    #2,sp
  127.     _ExittoShell
  128.  
  129.  
  130. ;-------------- InitSerial ------------------
  131. ; Open serial port for reads and writes, set
  132. ; the baud rate to 1200 baud and increase the
  133. ; size of the serial input buffer to 512 bytes
  134.  
  135. InitSerial
  136.     clr.w    -(sp)            ; room for routine results
  137.     move.w    #PortA,-(sp)        ; open the modem port (Port A)
  138.     jsr    OpenSerial
  139.     tst.w    (sp)            ; if Open failed, beep and quit.
  140.     bne.s    Abort
  141.     move.w    #PortA,-(sp)
  142.     move.w    #Config1200,-(sp)    ; set modem port to 1200 baud
  143.     jsr    Config
  144.     tst.w    (sp)            ; if Config failed, beep and quit.
  145.     bne.s    Abort
  146.     move.w    #PortA,-(sp)        ; make the serial input buffer
  147.     move.l    #512,-(sp)        ; 512 bytes big. Prevents data loss.
  148.     jsr    SetBuf
  149.     move.w    (sp)+,d0        ; clean up the stack, and abort if
  150.     bne.s    Abort            ; SetBuf failed.
  151.     rts
  152.  
  153.  
  154. ;--------------- Abort --------------------
  155.  
  156. Abort
  157.     move.w    #30,-(sp)
  158.     _Sysbeep
  159.     _ExitToShell            ; jump back to Finder
  160.  
  161.  
  162. ;------------ InitManagers -----------------
  163.  
  164. InitManagers
  165.     _MoreMasters            ; prevents heap fragmentation
  166.     move.l    #$ffffffff,d0
  167.     _NewHandle            ; compact heap
  168.     pea    -4(a5)            ; QuickDraw globals
  169.     _InitGraf
  170.     _InitFonts
  171.     move.l    #$0000ffff,d0        ; flush all events
  172.     _FlushEvents
  173.     _InitWindows
  174.     _InitMenus
  175.     clr.l    -(sp)            ; no restart procedure
  176.     _InitDialogs
  177.     _TEInit
  178.     _InitCursor
  179.     rts
  180.  
  181.  
  182. ;------------- SetupMenu ------------------
  183.  
  184. SetupMenu
  185. ;Apple menu:
  186.     clr.l    -(sp)
  187.     move.w    #AppleMenu, -(sp)
  188.     _GetRMenu            ; get Apple menu from the rsrc file
  189.     move.l    (sp),AppleMHdl(a5)     ; save handle to menu
  190.     move.l    (sp),-(sp)
  191.     clr    -(sp)
  192.     _InsertMenu
  193.     move.l    #'DRVR',-(sp)
  194.     _AddResMenu            ; add DA's to Apple menu
  195.  
  196. ;File menu:
  197.     clr.l    -(sp)
  198.     move.w    #FileMenu,-(sp)
  199.     _GetRMenu
  200.     move.l    (sp),FileMHdl(a5)    ; save handle to menu
  201.     clr    -(sp)
  202.     _InsertMenu
  203.  
  204. ;Edit menu:
  205.     clr.l    -(sp)
  206.     move.w    #EditMenu,-(sp)
  207.     _GetRMenu
  208.     move.l    (sp),EditMHdl(a5)    ; save handle to menu
  209.     clr    -(sp)
  210.     _InsertMenu
  211.  
  212. ;Command menu:
  213.     clr.l    -(sp)
  214.     move.w    #CmdMenu,-(sp)
  215.     _GetRMenu
  216.     move.l    (sp),CmdMHdl(a5)    ; save handle to menu
  217.     clr    -(sp)
  218.     _InsertMenu
  219.     move.l    CmdMHdl(a5),-(sp)    ; put handle on stack
  220.     move.w    #B1200,d0
  221.     move.w    d0,BaudChk(a5)
  222.     move.w    d0,-(sp)
  223.     move.w    #-1,-(sp)        ; next to the 1200 baud item
  224.     _CheckItem
  225.     _DrawMenuBar
  226.     rts
  227.  
  228.  
  229. ;------------ SetupWindow -----------------
  230.  
  231. SetupWindow
  232.     clr.l    -(sp)
  233.     move.w    #WindID,-(sp)
  234.     pea    WindowStorage(a5)
  235.     move.l    #-1,-(sp)        ; make it the top window
  236.     _GetNewWindow            ; load it from the rsrc file
  237.     move.l    (sp),WindowHdl(a5)    ; save handle
  238.     _SetPort            ; make it the current port
  239.     move.w    #monaco,-(sp)        ; Monaco
  240.     _TextFont
  241.     move.w    #9,-(sp)        ; in 9 pt.
  242.     _TextSize
  243.     rts
  244.  
  245.  
  246. ;----------  SetupTextEdit ----------------
  247.  
  248. SetupTextEdit
  249.     clr.l    -(sp)            ; space for text handle
  250.     pea    DestRect        ; DestRect Rectangle
  251.     pea    ViewRect        ; ViewRect Rectangle
  252.     _TENew
  253.     move.l    (sp)+,a0        ; save text handle
  254.     move.l    a0,a2            ; in a2
  255.     move.l    (a0),a0
  256.     move.b    #-1,teCROnly(a0)
  257.     move.w    #-1,-(sp)
  258.     move.l    a2,-(sp)        ; enable TE auto scroll (128K ROM)
  259.     _TEAutoView
  260.     rts
  261.  
  262.  
  263. ;---------------- CliptoTE ---------------
  264. ; CliptoTE copies text in the clipboard to the TE scrap
  265.  
  266. CliptoTE
  267.     move.l    #0,a3            ; check for TEXT in the desk scrap
  268.     bsr.s    @1
  269.     bmi.s    @2            ; leave if none
  270.  
  271.     move.l    #0,d0            ; lets get the scrap, but first
  272.     _NewHandle            ; get a handle for it
  273.     move.l    a0,a3
  274.     bsr.s    @1
  275.     move.l    TEScrpHandle,a0        ; replace old handle to TEScrap
  276.     _DisposHandle
  277.     move.l    a3,TEScrpHandle        ; with ours
  278.     move.l    TEScrpHandle,a0
  279.     _GetHandleSize            ; get length of our scrap
  280.     move.w    d0,TEScrpLength
  281. @2    rts                ; leave  CliptoTE
  282.  
  283. @1    clr.l    -(sp)            ; space for result
  284.     move.l    a3,-(sp)
  285.     move.l    #'TEXT',-(sp)        ; just check for TEXT
  286.     pea    GSOffset(a5)
  287.     _GetScrap
  288.     move.l    (sp)+,d0        ; return result
  289.     rts
  290.  
  291.  
  292. ;--------------- GetSerCh ----------------
  293.  
  294. GetSerCh
  295.     clr.l    -(sp)            ; room for character count
  296.     move.w    #PortA,-(sp)        ; if modem port has data, save it
  297.     pea    IOBuf(a5)        ; in this buffer.
  298.         jsr    GetSerial
  299.     move.l    (sp)+,CharCnt(a5)    ; get the # of characters received.
  300.     bra    NextEvent
  301.  
  302.  
  303. ;--------------- PutScreen ----------------
  304. ; PutScreen will display the characters in
  305. ; the buffer, taking care of some control
  306. ; characters. It uses TextEdit for display.
  307.  
  308. PutScreen
  309.     move.l    CharCnt(a5),d1        ; skip if no characters in buffer
  310.     beq    NextEvent
  311.     subq.l    #1,d1            ; adjust character count for loop
  312. PutTE    lea    IOBuf(a5),a0        ; point to the character buffers
  313.     lea    Outbuf(a5),a1
  314. TELoop    move.b    (a0)+,d0        ; get a char from the input buffer
  315.     andi.w    #$7f,d0            ; clear out 8th bit
  316.     cmpi.w    #$20,d0            ; if less than space, then it
  317.     blt.s    CtrlCh            ; must be a Ctrl character
  318. inBuf    move.b    d0,(a1)+        ; printable character
  319. inLoop    dbra    d1,TELoop
  320.     pea    Outbuf(a5)        ; print the sanitized output buffer
  321.     move.l    CharCnt(a5),-(sp)
  322.     move.l    a2,-(sp)
  323.     _TEInsert
  324.     move.l    a2,-(sp)
  325.     _TESelView            ; scroll if needed
  326.     bra    NextEvent        ; exit PutScreen
  327.  
  328.  
  329. ;----- handle control characters ----------
  330. ; Control characters are serviced here. A
  331. ; lookup table would be more efficient, in
  332. ; particular if we were to emulate a real
  333. ; terminal (like a VT-52 or VT-100).
  334.  
  335. CtrlCh    cmpi.w    #$0d,d0            ; let Text Edit take care of CR
  336.     beq.s    inBuf
  337.     cmpi.w    #8,d0            ; backspace
  338.     beq.s    BS
  339.     cmpi.w    #7,d0            ; bell
  340.     beq.s    Bell
  341.     cmpi.w    #9,d0            ; tab
  342.     beq.s    Tab
  343.     subq.l    #1,CharCnt(a5)        ; ignore anything else
  344.     bra.s    inLoop
  345.  
  346. BS    subq.l    #1,a1            ; move back outbuf pointer by 1
  347.     subq.l    #2,CharCnt(a5)        ; 1 for BS char, 1 for erased char
  348.     beq    NextEvent        ; no chars to print - all done.
  349.     bgt.s    inLoop            ; continue filtering
  350.  
  351.     move.w    d0,-(sp)        ; use TEKey to force backspace
  352.     move.l    a2,-(sp)        ; if backed out of input buffer
  353.     _TEKey
  354.     bra    NextEvent
  355.  
  356. Bell    move.w    #30,-(sp)        ; make a beep
  357.     _SysBeep
  358.     subq.l    #1,CharCnt(a5)        ; get rid of character
  359.     bra.s    inLoop
  360.  
  361. Tab    move.w    #4,d2            ; 5 spaces for a tab
  362. @1    move.b    #$20,(a1)+        ; put them into the output buffer
  363.     dbra    d2,@1
  364.     addq.l    #4,CharCnt(a5)        ; adjust the character count
  365.     bra.s    inLoop            ; ( # spaces, -1 for the tab char)
  366.  
  367.  
  368. ;------------- Handle Event  -------------
  369. ; This routine is the core of the program.
  370. ; The event number is used as an index into
  371. ; the EventTable. These entries cover all
  372. ; the events that could happen while the
  373. ; program is in the main loop.
  374.  
  375. HandleEvent
  376.     move.w    Modify(a5),d1
  377.     move.w    What(a5),d0        ; get event number
  378.     add.w    d0,d0            ; *2 for table index
  379.     move.w    EventTable(d0),d0    ; point to routine
  380.     jmp    EventTable(d0)        ; and jump to it
  381.  
  382. EventTable
  383.  
  384.     dc.w    NextEvent-EventTable    ;  0 (Null)
  385.     dc.w    MouseDown-EventTable    ;  1 mouse down
  386.     dc.w    NextEvent-EventTable    ;  2 mouse up        (Not used)
  387.     dc.w    KeyDown-EventTable    ;  3 key down
  388.     dc.w    NextEvent-EventTable    ;  4 key up        (Not used)
  389.     dc.w    KeyDown-EventTable    ;  5 auto-key
  390.     dc.w    Update-EventTable    ;  6 update
  391.     dc.w    NextEvent-EventTable    ;  7 disk inserted (Not used)
  392.     dc.w    Activate-EventTable    ;  8 activate
  393.     dc.w    NextEvent-EventTable    ;  9 abort         (Not used)
  394.     dc.w    NextEvent-EventTable    ; 10 network       (Not used)
  395.     dc.w    NextEvent-EventTable    ; 11 I/O driver    (Not used)
  396.  
  397.  
  398. ;-------------- Mouse down ----------------
  399.  
  400. MouseDown
  401.     clr.w     -(sp)            ; space for result
  402.     move.l    Point(a5),-(sp)        ; get mouse coordinates
  403.     pea    WWindow(a5)        ; Event Window
  404.     _FindWindow
  405.     move     (sp)+,d0        ; get region number
  406.     add    d0,d0            ; *2 for index into table
  407.     move.w    WindowTable(d0),d0    ; point to routine offset
  408.     jmp    WindowTable(d0)        ; jump to routine
  409.  
  410. WindowTable
  411.     dc.w    NextEvent-WindowTable    ; In Desk (Not used)
  412.     dc.w    InMenu-WindowTable    ; In Menu Bar
  413.     dc.w    SystemEvent-WindowTable ; In System Window
  414.     dc.w    Content-WindowTable    ; In Content
  415.     dc.w    Drag-WindowTable    ; In Drag
  416.     dc.w    NextEvent-WindowTable    ; In Grow (Not used)
  417.     dc.w    QuitRoutine-WindowTable    ; In Go Away
  418.  
  419.  
  420. ;---------------- in Menu -----------------
  421. InMenu
  422.     clr.l    -(sp)            ; make room on stack
  423.     move.l    Point(a5),-(sp)        ; mouse event
  424.     _MenuSelect
  425.     move.w     (sp)+,d0        ; save menu
  426.     move.w     (sp)+,d1         ; and menu item
  427.  
  428. Choices                    ; called by command key too
  429.     cmp.w     #AppleMenu,d0
  430.     beq.s     InAppleMenu
  431.     cmp.w     #FileMenu,d0
  432.     beq.s     InFileMenu
  433.     cmp.w     #EditMenu,d0
  434.     beq.s     InEditMenu
  435.     cmp.w     #CmdMenu,d0
  436.     beq     InCmdMenu
  437.  
  438. ChoiceReturn
  439.     bsr    UnHiliteMenu        ; unhighlight the menu bar
  440.     bra     NextEvent
  441.  
  442.  
  443. ;-------------- in InAppleMenu -----------------
  444. ; In the Apple menu.  If it wasn't About, it must have been a
  445. ; desk accessory.  If so, open the desk accessory.
  446.  
  447. InAppleMenu
  448.     cmp.w    #AboutItem,d1        ; is it About?
  449.     beq.s     About            ; if so go do About...
  450.     move.l    AppleMHdl(a5),-(sp)    ; look in Apple Menu
  451.     move.w     d1,-(sp)
  452.     pea    DeskName(a5)        ; get Item Name
  453.     _GetItem
  454.     clr     -(sp)            ; space for opening result
  455.     pea    DeskName(a5)        ; open Desk Acc
  456.     _OpenDeskAcc
  457.     move.w     (sp)+,d0        ; pop result
  458.  
  459. GoSetOurPort
  460.  
  461.     bsr     SetOurPort
  462.     bra.s    ChoiceReturn
  463.  
  464.  
  465. ;--------------- About --------------------
  466. ; Set up the About dialog box, and wait for
  467. ; the proper click or keypress.  End by
  468. ; closing the dialog box and setting the
  469. ; port to us.
  470.  
  471. About
  472.     clr.l    -(sp)            ; space for dialog pointer
  473.     move    #AboutDialog,-(sp)    ; dialog rsrc #
  474.     pea    DStorage(a5)
  475.     move.l    #-1,-(sp)        ; dialog goes on top
  476.     _GetNewDialog
  477.     move.l    (sp),-(sp)        ; copy handle for Close
  478.     _SetPort            ; make dialog box the port
  479.     move.l    a2,-(sp)
  480.     _TEDeActivate
  481.  
  482. WaitOK
  483.     clr.l    -(sp)            ; clear space for handle
  484.     pea    ItemHit(a5)
  485.     _ModalDialog            ; wait for a response
  486.     move.w    ItemHit(a5),d0        ; look to see what was hit
  487.     cmp.w    #ButtonItem,d0        ; was it OK?
  488.     bne.s     WaitOK
  489.     _CloseDialog            ; handle already on stack
  490.      bra.s    GoSetOurPort
  491.  
  492.  
  493. ;---------------- in FileMenu -----------------
  494.  
  495. inFileMenu
  496.     cmp.w    #QuitItem,d1        ; is it Quit?
  497.     bne.s     ChoiceReturn        ; no, go get next event
  498.     bsr    UnHiliteMenu        ; unhighlight the menu bar
  499.     bra    RealQuit        ; go Quit
  500.  
  501.  
  502. ;---------------- in EditMenu -----------------
  503. ; The Edit Menu support routines transfer the
  504. ; TE scrap to the clipboard, and back. See the
  505. ; clipboard chapter in Dan Weston's
  506. ; "Assembly Language Programming Volume II"
  507.  
  508. InEditMenu
  509.     bsr    SystemEdit        ; Desk accessory active?
  510.     bne.s     ChoiceReturn        ; yes, SystemEdit handled it
  511.     cmp.w    #CutItem,d1
  512.     beq.s    Cut
  513.     cmp.w    #CopyItem,d1
  514.     beq.s    Copy
  515.     cmp.w    #PasteItem,d1
  516.     beq.s    Paste
  517.     cmp.w    #ClearItem,d1
  518.     beq.s    ClearIt
  519.     bra    ChoiceReturn
  520.  
  521. Cut
  522.     move.l    a2,-(sp)
  523.     _TECut                ; Cut and copy text
  524.     bra.s     Convert
  525.  
  526. Copy
  527.     move.l    a2,-(sp)
  528.     _TECopy                ; Copy text to scap
  529.      bra.s    Convert
  530.  
  531. Paste
  532.     bsr    CliptoTE        ; from the clipboard
  533.     move.l    a2,-(sp)
  534.     _TEPaste            ; Paste
  535.     bra     ChoiceReturn
  536.  
  537. ClearIt
  538.     move.l    a2,-(sp)
  539.     _TEDelete            ; Clear without copying
  540.  
  541. Convert
  542.     bsr.s    TEtoClip        ; copy to clipboard
  543.     bra     ChoiceReturn
  544.  
  545. ;-------------- TEtoClip ---------------------
  546. ; TEtoClip copies the TE scrap to the Clipboard
  547.  
  548. TEtoClip
  549.     move.l    TEScrpHandle,a0
  550.     _GetHandleSize            ; get length of our scrap
  551.     move.l    d0,a3            ; save length
  552.     clr.l    -(sp)            ; space for result
  553.     _ZeroScrap            ; want to write over scrap
  554.     move.l    (sp)+,d0
  555.     move.l    TEScrpHandle,a0
  556.     _Hlock                ; lock pointer to our scrap
  557.     clr.l    -(sp)            ; space for result
  558.     move.l    a3,-(sp)
  559.     move.l    #'TEXT',-(sp)        ; just check for TEXT
  560.     move.l    TEScrpHandle,a0
  561.     move.l    (a0),-(sp)        ; save pointer to TE scrap
  562.     _PutScrap
  563.     move.l    (sp)+,d0
  564.     move.l    TEScrpHandle,a0
  565.     _HUnLock            ; unlock handle
  566.     rts                ; leave TEtoClip
  567.  
  568.  
  569. ;---------------- in CmdMenu ------------------
  570.  
  571. InCmdMenu
  572.     cmp.w    #EraseItem,d1        ; baud rate change?
  573.     bne.s    InBaud
  574.  
  575. ; it wasn't the baud change command, so fall through to erase screen
  576.  
  577.     move.l    #0,-(sp)        ; set Selection range to cover
  578.     move.l    #$ffff,-(sp)        ; everything in this TE block.
  579.     move.l    a2,-(sp)
  580.     _TESetSelect
  581.     bra.s     ClearIt            ; and clear them out
  582.  
  583.  
  584. ;---------------- in BaudMenu -----------------
  585.  
  586. InBaud
  587.     cmp.w    #B300,d1
  588.     beq.s    @1
  589.     cmp.w    #B1200,d1
  590.     beq.s    @2
  591.     cmp.w    #B2400,d1
  592.     beq.s    @3
  593.     cmp.w    #B9600,d1
  594.     beq.s    @4
  595.     bra    NextEvent
  596.  
  597. @1    move.w    #Config300,SerCon(a5)
  598.     bra.s    @5
  599. @2    move.w    #Config1200,SerCon(a5)
  600.     bra.s    @5
  601. @3    move.w    #Config2400,SerCon(a5)
  602.     bra.s    @5
  603. @4    move.w    #Config9600,SerCon(a5)
  604. @5    move.l    CmdMHdl(a5),-(sp)
  605.     move.w    BaudChk(a5),-(sp)    ; uncheck previous item
  606.     move.w    d1,BaudChk(a5)        ; save new baud item
  607.     move.w    #0,-(sp)
  608.     _CheckItem
  609.     move.l    CmdMHdl(a5),-(sp)    ; put handle on stack
  610.     move.w    BaudChk(a5),-(sp)    ; and place a check
  611.     move.w    #-1,-(sp)        ; next to the current baud
  612.     _CheckItem
  613.     clr.w    -(sp)
  614.     move.w    #PortA,-(sp)        ; set the new baud rate
  615.     move.w    SerCon(a5),-(sp)
  616.     jsr    Config
  617.     move.w    (sp)+,d0        ; ignore the result
  618.     bra     ChoiceReturn
  619.  
  620.  
  621. ;------------- UnhiliteMenu ---------------
  622.  
  623. UnhiliteMenu
  624.     clr.w    -(sp)            ; all menus
  625.     _HiLiteMenu
  626.     rts
  627.  
  628.  
  629. ;--------------- SystemEdit ----------------
  630.  
  631. SystemEdit
  632.     clr     -(sp)            ; space for result
  633.     move.w    d1,-(sp)        ; get item in Edit menu
  634.     subq    #1,(sp)            ; SystemEdit is off by 1
  635.     _SysEdit
  636.     move.b     (sp)+,d0
  637.     rts
  638.  
  639.  
  640. ;-------------- SystemEvent ---------------
  641.  
  642. SystemEvent
  643.     pea    EventRecord(a5)
  644.     move.l    WWindow(a5),-(sp)
  645.     _SystemClick            ; let the system do it
  646.     bra     NextEvent
  647.  
  648.  
  649. ;-------------- in Content ----------------
  650.  
  651. Content
  652.     clr.l    -(sp)            ; room for result
  653.     _FrontWindow
  654.     move.l    (sp)+,d0        ; front window pointer
  655.     cmp.l    WindowHdl(a5),d0        ; same as our pointer?
  656.     beq.s    @1            ; ignore it
  657.     move.l    WWindow(a5),-(sp)
  658.     _SelectWindow            ; do it, fall through to NextEvent
  659.     bra    NextEvent
  660.  
  661. @1    pea    Point(a5)
  662.     _GlobalToLocal
  663.     move.l    Point(a5),-(sp)
  664.     btst    #9,d1
  665.     sne    d0
  666.     move.b    d0,-(sp)
  667.     move.l    a2,-(sp)
  668.     _TEClick
  669.     bra    NextEvent
  670.  
  671. ;---------------- in Drag -----------------
  672.  
  673. Drag
  674.     move.l    WWindow(a5),-(sp)
  675.     move.l    Point(a5),-(sp)
  676.     pea    WBounds
  677.     _DragWindow            ; drag window and fall through
  678.     bra    NextEvent
  679.  
  680. ;--------------- Quit Routine -----------------
  681.  
  682. QuitRoutine
  683.     clr.w    -(sp)            ; room for result
  684.     move.l    WindowHdl(a5),-(sp)    ; get pointer to open window
  685.     move.l    Point(a5),-(sp)        ; mouse point
  686.     _TrackGoAway
  687.     move.w    (sp)+,d0
  688.     beq    NextEvent        ; didn't really want to quit
  689.  
  690. RealQuit
  691.     move.l    WindowHdl(a5),-(sp)    ; did want to quit
  692.     _CloseWindow
  693.     move.w    #-1,d0            ; d0 is TRUE - ok to quit
  694.     rts
  695.  
  696.  
  697. ;--------------- Key down -----------------
  698.  
  699. KeyDown
  700.     move.w    Message+2(a5),d0    ; get key code and character
  701.     btst    #8,d1            ; command key pressed?
  702.     beq.s    SaveCh            ; yes, take care of it.
  703.     andi.w    #$001f,d0        ; convert to a control character
  704. SaveCh    move.b    d0,IOBuf(a5)        ; save it in the buffer
  705.     move.l    #1,CharCnt(a5)        ; send the character typed
  706.     clr.w    -(sp)            ; room for dummy result
  707.     move.w    #PortA,-(sp)        ; in the input buffer
  708.     pea    IOBuf(a5)
  709.     pea    CharCnt(a5)
  710.     jsr    PutSerial        ; and send it out the modem port
  711.     move.w    (sp)+,d0        ; get rid of dummy result
  712.     bra.s    NextEvent
  713.  
  714.  
  715. ;----------------- Update -----------------
  716.  
  717. Update
  718.     move.l    WindowHdl(a5),-(sp)
  719.     _BeginUpdate
  720.     pea    ViewRect        ; erase visible window
  721.     _EraseRect
  722.     pea    ViewRect
  723.     move.l    a2,-(sp)
  724.     _TEUpdate
  725.     move.l    WindowHdl(a5),-(sp)
  726.     _EndUpdate
  727.     bra.s    NextEvent
  728.  
  729.  
  730. ;---------------- Activate ----------------
  731.  
  732. Activate
  733.     move.l    WindowHdl(a5),d0
  734.     cmp.l    Message(a5),d0        ; our window?
  735.     bne.s    NextEvent
  736.     btst    #0,d1            ; activate?
  737.     beq.s    Deactivate        ; no
  738.  
  739.     move.l    a2,-(sp)        ; move Text Handle To Stack
  740.     _TEActivate
  741.     move.l    EditMHdl(a5),-(sp)    ; get handle to the menu
  742.     move.w    #UndoItem,-(sp)        ; disable 1st item (undo)
  743.     _DisableItem
  744.  
  745. SetOurPort
  746.     move.l    WindowHdl(a5),-(sp)
  747.     _SetPort
  748.     bra.s    NextEvent
  749.  
  750. ; Deactivate window, turn off TextEdit, enable undo for the desk
  751. ; accessories.
  752.  
  753. Deactivate
  754.     move.l    a2,-(sp)        ; get Text Handle
  755.     _TeDeActivate
  756.     move.l    EditMHdl(a5),-(sp)    ; get handle to the menu
  757.     move.w    #UndoItem,-(sp)        ; enable 1st item (undo)
  758.     _EnableItem
  759. ;    bra     NextEvent        ; *CAUTION!* if more code
  760. ; is added after this routine, remember to uncomment the line above!
  761.     
  762.  
  763. ;--------------- Next Event ---------------
  764.  
  765. NextEvent
  766.     moveq    #0,d0            ; say that it's not Quit
  767.     rts                ; return to EventLoop
  768.  
  769.  
  770.  
  771. ;------------ Event variables ------------
  772. ; IMPORTANT! remember, the EventRecord is
  773. ; very much a variable and NOT a constant.
  774. ; Never declare the EventRecord variables
  775. ; with a dc command.
  776.  
  777. EventRecord    ds.w    0
  778. What:         ds.w     1        ; event number
  779. Message:    ds.l    1
  780. When:        ds.l    1
  781. Point:        ds.l    1        ; mouse coordinates
  782. Modify:        ds.w     1        ; key and button state
  783.  
  784. ;------------- Window stuff ---------------
  785.  
  786. WWindow        ds.l    1
  787. ViewRect    dc.w     5,4,290,500    ; Text Record's View Rect
  788. DestRect    dc.w     5,4,290,500    ; Text Record's Dest Rect
  789. WBounds        dc.w     5,5,335,510
  790.  
  791. ;------- Application variables ------------
  792.  
  793. AppleMHdl    ds.l    1        ; handle for apple menu
  794. FileMHdl    ds.l    1        ; handle for file menu 
  795. EditMHdl    ds.l    1        ; handle for edit menu 
  796. CmdMHdl        ds.l    1        ; handle for command menu 
  797.  
  798. DStorage    ds.w    DWindLen
  799. DeskName    ds.w    16        ; DA name
  800. ItemHit        ds.w    1
  801. WindowStorage    ds.w    WindowSize
  802. WindowHdl    ds.l    1        ; handle to the window
  803. GSOffset    ds.l    1        ; Get Scrap Offset dummy
  804.  
  805.  
  806. ;Serial port variables
  807. IOBuf        ds.b    512        ; general I/O buffer
  808. Outbuf        ds.b    512        ; sanitized version of IOBuf
  809. SerCon        ds.w    1        ; current serial port config
  810. BaudChk        ds.w    1        ; current checked item
  811. CharCnt        ds.l    1        ; # of characters read
  812.  
  813.     end
  814.